﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Warensoft.Utility;
using Warensoft.Socket.EventArgs;
using System.IO;
using Warensoft.Socket.Extension;
using Warensoft.Socket.MessageDataStructs;
using System.Diagnostics;
namespace Warensoft.Socket
{
    public abstract class ClientSessionBase:IDisposable 
    {
        private Dictionary<string, object> sessionProperties = new Dictionary<string, object>();
        private ClientSocket clientSocket = null;
        public bool SocketDisconnected { get { return this.clientSocket.SocketDisconnected; } }
        public event EventHandler <DisconnectedEventArgs >Disconnected;
        public event EventHandler NewMessage;
        public event EventHandler MessageSent;
        public event EventHandler<ErrorEventArgs> OnError;
        public string Name { get; set; }
        public ClientSocket ClientSocket
        {
            get
            {
                return this.clientSocket;
            }
        }
        public Application  Application
        {
            get;
            set;
        }
        public SocketServer Server
        {
            get
            {
                return this.clientSocket.Server;
            }
        }
        public object this[string name]
        {
            get
            {
                return this.sessionProperties[name];
            }
            set
            {
                lock (this)
                {
                    this.sessionProperties[name] = value;
                }
            }
        }
       
        public ClientSessionBase(ClientSocket socket)
        {
            this.clientSocket = socket;
            this.clientSocket.NewMessage += new EventHandler<NewMessageEventArgs>(clientSocket_NewMessage);
            this.clientSocket.Disconnected += new EventHandler<DisconnectedEventArgs >(clientSocket_Disconnected);
            this.clientSocket.MessageSent += new EventHandler<NewMessageEventArgs>(clientSocket_MessageSent);
        }
        /// <summary>
        /// 开始接收消息
        /// </summary>
        public void StartReceive()
        {
            this.clientSocket.StartReceive();
        }
       
        void clientSocket_MessageSent(object sender, NewMessageEventArgs e)
        {
            e.MessageStream .Close ();
            e.MessageStream = null;
            GC.Collect();
            if (this.MessageSent !=null )
            {
                this.MessageSent(this, new System.EventArgs());
            }
        }
        
        void clientSocket_Disconnected(object sender, DisconnectedEventArgs  e)
        {
            this.OnDisconnected();
            if (Disconnected == null)
            {
                this.Server.AddOrRemoveSession(this, SessionListOption.Remove );
                Trace.WriteLine("-------------------------------------------------------------------------------------");
            }
            if (Disconnected !=null )
            {
                Disconnected(this, e);
            }
        }

        void clientSocket_NewMessage(object sender, NewMessageEventArgs e)
        {
            e.MessageStream.ResetStreamPointer  ();
            try
            {
                var msg = e.MessageStream as MessageDataStructs.PackageBase;
                msg.Application = this.Application;
                this.OnNewMessage(msg);
            }
            catch (Exception ex)
            {
                if (this.OnError != null)
                {
                    this.OnError(this, new ErrorEventArgs(ex) );
                }
            }
            finally
            {
                e.MessageStream .Close ();
                e.MessageStream = null;
                GC.Collect();
                if (this.NewMessage != null)
                {
                    this.NewMessage(this, new System.EventArgs());
                }
            }
            
        }
       
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="message">消息内容</param>
        public void SendMessage(PackageBase  message)
        {
            this.clientSocket.SendMessage(message );
        }
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="message">消息内容</param>
        public void SendMessage(Message message)
        {
            this.clientSocket.SendMessage(message);
        }
        /// <summary>
        /// 当Socket断开时会调用些函数
        /// </summary>
        public abstract void OnDisconnected();
        /// <summary>
        /// 当有新消息到达时会被调用
        /// </summary>
        /// <param name="message"></param>
        public abstract void OnNewMessage(MemoryStream  message);
        protected  void OnErrorMessage(Exception ex)
        {
            if (this.OnError != null)
            {
                this.OnError(this, new ErrorEventArgs(ex));
            }
        }
        private EventLog log = new EventLog();
        public void WriteLog(string content)
        {
            if (EventLog.SourceExists("Session Log") == false)
            {
                EventLog.CreateEventSource("Session Log", "Warensoft Socket Server Log");
            }
            this.log.Source = "Session Log";
            this.log.WriteEntry(content, EventLogEntryType.Information);
        }

        #region IDisposable Members

        public void Dispose()
        {
            this.clientSocket.Dispose();
            this.clientSocket = null;
            this.log.Close();
            this.sessionProperties.Clear();
            this.sessionProperties = null;
            
        }

        #endregion
    }
}
